﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RainEngine.Controllers;
using RainEngine.SceneManagement;

namespace RainEngine.SceneNodes.UI
{
    /// <summary>
    /// 复选框控件
    /// </summary>
    public class UICheckBox : UIButtonBase
    {
        #region 成员变量和构造函数

        //默认值
        private static readonly Vector2 DefaultCheckBoxImageSize = new Vector2(16, 16);
        private static readonly Rectangle DefaultRectSource = new Rectangle(0, 0, 13, 13);
        private static readonly Rectangle DefaultRectHighlight = new Rectangle(13, 0, 13, 13);
        private static readonly Rectangle DefaulRectChecked = new Rectangle(0, 39, 13, 13);
        private static readonly Rectangle DefaulRectHighlightChecked = new Rectangle(13, 39, 13, 13);
        private static readonly Color DefaultTextColor = Color.White;
        private static readonly Color DefaultTextHighlight = Color.Red;

        /// <summary>
        /// 文字与左侧图像框的水平距离，默认为5.
        /// </summary>
        protected float textOffsetX = 5.0f;

        /// <summary>
        /// 复选框选中时的纹理的源矩形
        /// </summary>
        protected Rectangle rectSourceChecked;

        /// <summary>
        /// 复选框选中时的高亮状态的纹理源矩形
        /// </summary>
        protected Rectangle rectSourceHighlightChecked;

        /// <summary>
        /// 复选框是否被选中
        /// </summary>
        protected bool _checked = false;

        /// <summary>
        /// 复选框是否可以被Uncheck
        /// </summary>
        protected bool canUncheck = true;

        /// <summary>
        /// 左侧图像的大小
        /// </summary>
        private Vector2 imageSize;

        /// <summary>
        /// 创建一个新UICheckBox对象，默认文字为"CheckBox"，默认文字颜色为白色。
        /// </summary>
        /// <param name="engine">引擎</param>
        /// <param name="setScene">所属的Scene</param>
        public UICheckBox(RainGE engine, Scene setScene)
            : this(engine, setScene, Vector2.Zero, "UICheckBox", DefaultCheckBoxImageSize, "CheckBox", engine.DefaultFont, DefaultTextColor, DefaultTextHighlight, DefaultRectSource, DefaultRectHighlight, DefaulRectChecked, DefaulRectHighlightChecked,true)
        {

        }

        /// <summary>
        /// 主要用于RadioButton继承
        /// </summary>
        /// <param name="engine">引擎</param>
        /// <param name="setScene">选择框所属的scene</param>
        /// <param name="setText">选择框上的文字</param>
        /// <param name="setTextureName">选择框所使用的纹理名称</param>
        internal UICheckBox(RainGE engine, Scene setScene, string setText, string setTextureName)
            : this(engine, setScene, Vector2.Zero, setTextureName, DefaultCheckBoxImageSize, setText, engine.DefaultFont, DefaultTextColor, DefaultTextHighlight, DefaultRectSource, DefaultRectHighlight, DefaulRectChecked, DefaulRectHighlightChecked,true)
        { }

        /// <summary>
        /// 创建一个新UICheckBox对象，内部方法，只能在引擎内部调用。
        /// </summary>
        /// <param name="engine">引擎</param>
        /// <param name="setScene">所属的Scene</param>
        /// <param name="setPosition">文字的2D屏幕位置</param>
        /// <param name="setTextureName">选择框所使用的纹理名称</param>
        /// <param name="setText">文字</param>  
        /// <param name="setSize">选择框左侧的图像大小</param>
        /// <param name="setFont">字体</param>
        /// <param name="setTextColor">文字普通状态的颜色</param>
        /// <param name="setTextColorHighlight">文字高亮状态的颜色</param>
        /// <param name="setRectOrigin">普通状态的纹理矩形</param>
        /// <param name="setRectHighlight">高亮状态的纹理矩形</param>
        /// <param name="setRectChecked">选中时普通状态的纹理矩形</param>
        /// <param name="setRectHighlightChecked">选中时高亮状态的纹理矩形</param>              
        internal UICheckBox(RainGE engine, Scene setScene, Vector2 setPosition, string setTextureName, Vector2 setSize, string setText, SpriteFont setFont, Color setTextColor, Color setTextColorHighlight, Rectangle setRectOrigin, Rectangle setRectHighlight, Rectangle setRectChecked, Rectangle setRectHighlightChecked,bool useResource)
            : base(engine, setScene, setPosition, setTextureName, setSize, setText, setFont, setTextColor, setTextColorHighlight, setRectOrigin, setRectHighlight,useResource )
        {
            this.rectSourceChecked = setRectChecked;
            this.rectSourceHighlightChecked = setRectHighlightChecked;

            imageSize = setSize;
            //设置单选框大小
            ResetSize();
        }

        #endregion

        #region 属性

        /// <summary>
        /// 获取或设置文字与图像框的水平距离
        /// </summary>
        public float TextOffset
        {
            get { return textOffsetX; }
            set { textOffsetX = value; }
        }

        /// <summary>
        /// 获取或设置控件选中时的纹理的源矩形
        /// </summary>
        public Rectangle RectSourceChecked
        {
            get { return rectSourceChecked; }
            set { rectSourceChecked = value; }
        }

        /// <summary>
        /// 获取或设置控件选中时的高亮状态的纹理源矩形
        /// </summary>
        public Rectangle RectSourceHighlightChecked
        {
            get { return rectSourceHighlightChecked; }
            set { rectSourceHighlightChecked = value; }
        }

        /// <summary>
        /// 获取或设置控件是否被选中
        /// </summary>
        public bool Checked { get { return _checked; } set { _checked = value; } }

        /// <summary>
        /// 获取或设置复选框是否可以被Uncheck
        /// </summary>
        public bool CanUncheck { get { return canUncheck; } set { canUncheck = value; } }

        #endregion

        #region 事件

        /// <summary>
        /// 当选中项改变时发生的事件
        /// </summary>
        public event EventHandler CheckedChanged;

        /// <summary>
        /// 引发CheckedChanged事件。
        /// OnCheckedChanged方法允许继承的类处理这个事件。
        /// 注意：当在继承类中覆写OnCheckedChanged时，一定要调用基类的OnCheckedChanged方法才可以注册委托
        /// </summary>
        /// <param name="e"></param>
        public virtual void OnCheckedChanged(EventArgs e)
        {
            if (_checked && canUncheck)
                _checked = false;
            else if (!_checked)
                _checked = true;
            if (CheckedChanged != null)
            {
                CheckedChanged(this, e);
            }
        }

        /// <summary>
        /// 文本改变时的处理程序
        /// </summary>
        /// <param name="e"></param>
        protected override void OnTextChanged(EventArgs e)
        {
            ResetSize();
            base.OnTextChanged(e);
        }

        /// <summary>
        /// 字体改变时的处理程序
        /// </summary>
        /// <param name="e"></param>
        protected override void OnFontChanged(EventArgs e)
        {
            ResetSize();
            base.OnFontChanged(e);
        }

        /// <summary>
        /// 重置单选框大小
        /// </summary>
        private void ResetSize()
        {
            //如果复选框包含文字，则复选框的大小长为imageSize.X + textOffsetX + value.MeasureString(text).X，高为value.MeasureString(text).Y和imageSize.Y中的大的那个
            if (text != null)
                size = new Vector2(imageSize.X + textOffsetX + font.MeasureString(text).X, font.MeasureString(text).Y > imageSize.Y ? font.MeasureString(text).Y : imageSize.Y);
            //如果复选框不包含文字，则它的大小就是左侧图像框的大小
            else
                this.size = imageSize;

        }
        #endregion

        /// <summary>
        /// 绘制复选框
        /// </summary>
        /// <param name="gameTime"></param>
        public override int Draw(GameTime gameTime)
        {

            //如果文字不为null，则绘制文字
            if (text != null)
            {
                Color textColor = isMouseInside || (uiManager.ActiveControl == this) ? textColorHighlight : TextColor;

                // 设置文本的淡入淡出的透明度
                Color alphaTextColor = new Color(textColor.R, textColor.G, textColor.B, Scene.TransitionAlpha);
                //绘制文本
                RainGE.SpriteBatch.DrawString(font, text, new Vector2(Position.X + imageSize.X + textOffsetX, Position.Y + size.Y / 2 - font.MeasureString(text).Y / 2), alphaTextColor, Rotation, Origin, 1.0f, SpriteEffect, LayerDepth);
            }

            //获取图像淡入淡出的透明颜色
            alphaTextureColor = new Color(Color.R, Color.G, Color.B, Scene.TransitionAlpha);

            if (!_checked)
            {
                //根据鼠标移入还是按下设置图像源矩阵
                Rectangle rect = isMouseInside || (uiManager.ActiveControl == this) ? rectSourceHighlight : rectSourceOrigin;
                //绘制按钮背景图像
                RainGE.SpriteBatch.Draw(texture, new Rectangle((int)Position.X, (int)(Position.Y + size.Y / 2 - imageSize.Y / 2), (int)imageSize.X, (int)imageSize.Y), rect, alphaTextureColor, Rotation, Origin, SpriteEffect, LayerDepth);
            }
            else
            {
                //根据鼠标移入还是按下设置图像源矩阵
                Rectangle rect = isMouseInside || (uiManager.ActiveControl == this) ? rectSourceHighlightChecked : rectSourceChecked;
                //绘制按钮背景图像
                RainGE.SpriteBatch.Draw(texture, new Rectangle((int)Position.X, (int)(Position.Y + size.Y / 2 - imageSize.Y / 2), (int)imageSize.X, (int)imageSize.Y), rect, alphaTextureColor, Rotation, Origin, SpriteEffect, LayerDepth);
            }

            //鼠标点击切换选中状态
            if (isMouseInside && Input.MouseLeftButtonJustPressed)
            {
                this.OnCheckedChanged(EventArgs.Empty);
            }
            return 1;
        }
    }
}
